#pragma once

#include "Game/Process/RenderProcess.h"
#include "Render/Texture/Picture2DTexture.h"
#include "Render/Texture/RenderTarget.h"
#include "Render/Tradition/RHIRenderPass.h"
#include "Render/Tradition/GraphicsPipeline.h"
#include "Render/Texture/ColorRenderTarget.h"
#include "Render/Texture/CubemapTexture.h"
#include "Render/Texture/DepthRenderTarget.h"
#include "Render/Shader/RHIDescriptor.h"
#include "Render/Tradition/RHIFramebuffer.h"
#include "LocalEntity.h"
#include "LocalShader.h"
#include "Render/Raytracing/RayTracingPipeline.h"
#include "Render/Raytracing/TopLevelAccelerationStructure.h"
#include "RayTracingMath.h"


class BvhProcess : public RenderProcess
{
	DECLARE_PROCESS(BvhProcess)

	struct Ubo
	{
		glm::mat4 proj;
		glm::mat4 view;
	};

	struct RayConsts
	{
		glm::vec4 position[2];
		glm::vec4 color;
	};

	struct BVHBuffer
	{
		BVHNode* node;

		BVHBuffer* left;
		BVHBuffer* right;

		RefCountPtr<VertexBuffer> buffer;
	};

public:

	int32 mBvhDepth;

	bool mCaptureRay;

	bool mUseSAH;

	bool mShowHit;

protected:

	virtual void OnInit() override;

	virtual void OnTick(float deltaTime) override;

	virtual void OnResize() override;

	virtual void OnExit() override;

	BVHBuffer* BuildBVHBuffer(BVHNode* node);

	void DrawBVH(VkCommandBuffer commandBuffer, BVHBuffer* buffer, int32 depth);

	void FreeBVHBuffer(BVHBuffer* buffer);

	HitResult FindHitNode(Ray& ray, BVHNode* node);

protected:

	RayConsts mRayConsts;

	int32 mLastMouseX;

	int32 mLastMouseY;

	glm::vec4 mSelectColor;

	glm::vec4 mUnSelectColor;

	BVHNode* mBvhTree;

	BVHNode* mSahBvhTree;

	BVHBuffer* mBvhBuffer;

	BVHBuffer* mSahBvhBuffer;

	HitResult mHitResult;

	std::vector<Triangle> mTriangles;

	RefCountPtr<IndexBuffer> mIndexBuffer;

	RefCountPtr<RHIBuffer> mUboBuffer;

	RefCountPtr<RHIDescriptor> mDescriptor;

	DescriptorMask mDescriptorMask;

	RefCountPtr<GraphicsPipeline> mPipeline;

	RefCountPtr<RHIDescriptor> mRayDescriptor;

	DescriptorMask mRayDescriptorMask;

	RefCountPtr<GraphicsPipeline> mRayPipeline;

	std::vector<LocalEntity*> mLocalEntitys;

};
